package angels.client.Services;	
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import angels.client.Entities.Categories.Type;
import angels.client.Entities.Sharing;
import angels.client.Listeners.BroadcastListener;
import angels.client.Listeners.MainMenuListener;
import angels.client.Listeners.TrafficListener;
import angels.client.Tasks.GPSTask;
import angels.client.Tasks.GetCategoriesTask;
import angels.client.Tasks.SampleTrafficTask;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.location.Location;
import android.os.Binder;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.widget.Toast;

public class BusyHourService extends Service implements OnSharedPreferenceChangeListener{
    List<BroadcastListener> broadcast_listeners;
    List<TrafficListener> traffic_listeners;
	SharedPreferences prefs;
	String userName;
	boolean statusBarIcon;
	boolean samplingEnabled;
	long sampleInterval;
    Timer sampleTimer;	
	boolean reportingEnabled;
    long reportInterval;
	Timer reportTimer;
	final IBinder mBinder = new LocalBinder();
    Sharing[] last_traffic_update;
    public Location myLocation=null;
    public String category, subcategory;
    
	//onCreate method of the service (kind of like constructor) - reloads prefernces of user
	@Override
	public void onCreate(){
		super.onCreate();
				
		broadcast_listeners = new LinkedList<BroadcastListener>();
		traffic_listeners = new LinkedList<TrafficListener>();
        
		prefs = PreferenceManager.getDefaultSharedPreferences(this);
		prefs.registerOnSharedPreferenceChangeListener(this);
		
		// initiate class according to preferences
		reloadPrefs();
		
	}

	@Override
    public void onDestroy () {
	    prefs.unregisterOnSharedPreferenceChangeListener(this);
        // Shut down services
        setSamplingEnabled(false);
        super.onDestroy();
    }
	
	//reloads preferences of the user to the applications service
	private void reloadPrefs() {
		
	    setSampleInterval(Long.parseLong(prefs.getString("sampleInterval", "60000"))); // first set the interval
        setSamplingEnabled(prefs.getBoolean("sampleTraffic", false));
        
	    userName=prefs.getString("userName", "Ilan Arbiv");
	}
	
	protected void setSamplingEnabled(boolean isEnabled) 
    {
        if (samplingEnabled == isEnabled) return;
        samplingEnabled = isEnabled;
        setSampleTimerEnabled(isEnabled);
    }

	/*
	 * Helper function for the above and below methods
	 */
    private void setSampleTimerEnabled(boolean isEnabled) {
        
        // Must destroy old timer so we can change interval
        if (sampleTimer != null) { 
            sampleTimer.cancel();
            sampleTimer = null;
        }
        
        if (isEnabled) {
            sampleTimer = new Timer("Sampling timer");
            
            TimerTask timedSampleTask = new SampleTrafficTask(this);
            
            sampleTimer.schedule(timedSampleTask, 100, sampleInterval);
        } 
    }
	
	protected void setSampleInterval(long interval) {
        
        if (sampleInterval == interval)
            return;
        
        sampleInterval = interval;
        
        if (samplingEnabled) { // restarts the timer...
            setSampleTimerEnabled(false);
            setSampleTimerEnabled(true);
        }
    }

	public class LocalBinder extends Binder {
       public BusyHourService getService() {
            return BusyHourService.this;
        }
    }
		
	@Override
	public IBinder onBind(Intent arg0) {
		return mBinder;
	}

	public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
		reloadPrefs();
	}
	
	public String getRobotsURL(String category,String subcategory) {
		String server = prefs.getString("serverAddress", "http://angels-demo.appspot.com");
		//String server="http://busy-hour.appspot.com";
		return server + "/traffic?cat="+category+"&sub="+subcategory;
	}
	
    public void addTrafficListener(TrafficListener listener) {
        traffic_listeners.add(listener);
    }
    
    public void removeTrafficListener(TrafficListener listener) {
        traffic_listeners.remove(listener);
    }
    
    public Sharing[] getLatestTrafficUpdate() {
        return last_traffic_update;
    }
    
    //Notifies traffic updates to every activity that listens to the 
    public synchronized void notifyTraffic(Sharing[] robots) {
        
        last_traffic_update = robots;
        
        for (TrafficListener listener : traffic_listeners) 
            listener.onTrafficSampled(robots);
    }
    
    public synchronized void getMyLocation() {
    	Timer timer = new Timer("GPS timer");
        TimerTask timedSampleTask = new GPSTask(this);
        timer.schedule(timedSampleTask, 0);
        new CountDownTimer(10000, 3000) {

            public void onTick(long millisUntilFinished) {
               //called every 300 milliseconds, which could be used to
                   //display some crude animation
            	Toast.makeText(getApplicationContext(), "Getting GPS Singal...", Toast.LENGTH_SHORT).show();
            }

            public void onFinish() {
                //After 60000 milliseconds (60 sec) finish current 
                    //activity and open next activity
            	if (myLocation!=null)
            		Toast.makeText(getApplicationContext(), "Got GPS Singal!", Toast.LENGTH_SHORT).show();
            	else
            		Toast.makeText(getApplicationContext(), "No GPS Singal", Toast.LENGTH_SHORT).show();
            }
         }.start();
    }

	public String getCategoryURL(Type type, String selectedCategory) {
		String server = prefs.getString("serverAddress", "http://angels-demo.appspot.com");
		switch (type){
		case category:
			return  server+"/get_categories?type=cat";
		case subcategory:
			return  server+"/get_categories?type=sub&cat="+selectedCategory;
		}
		return null;
	}
	
	public void getCategories(MainMenuListener listener,Type type,String selectedCategory){
		Timer timer = new Timer("Categories timer");
        TimerTask timedSampleTask = new GetCategoriesTask(this,listener,type,selectedCategory);
        timer.schedule(timedSampleTask, 0);
	}
}